package br.cefetpe.tsi.game.base.views;

import static java.lang.Math.cos;
import static java.lang.Math.sin;
import static java.lang.Math.toRadians;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

import br.cefetpe.tsi.game.base.Disk;
import br.cefetpe.tsi.game.base.Roullette;

/**
 * 
 * @author F�bio
 * 
 */
public class TriangleView {
	public Triangle triangle;

	public Point2D.Double center;

	public Color color;

	public HexagonView hexagonView = null;

	public TriangleView(Triangle t, Color c) {
		this.triangle = t;
		this.color = c;
	}

	/**
	 * Constructor to be used to call the drawDisk.
	 * 
	 * @param t -
	 *            Triangle to Shape the disk and the roullette
	 */
	public TriangleView(Triangle t) {
		this.triangle = t;
	}

	/**
	 * Costructor used to call the drawRoullette method.
	 * 
	 * @param center -
	 *            the center of the roullete, which is the center of the center
	 *            disk
	 * @param side -
	 *            side of one triangle in disk
	 */
	public TriangleView(Point2D.Double center, double side) {
		Triangle t = new Triangle(center, side);
		this.triangle = t;
		HexagonView hv = new HexagonView(center, side);
		this.hexagonView = hv;
	}

	public TriangleView(Point2D.Double top, double side, Color c) {
		Triangle t = new Triangle(top, side);
		this.triangle = t;
		this.color = c;
	}

	public void draw(Graphics g) {
		Graphics2D g2d = (Graphics2D) g;
		g2d.setColor(this.color);
		g2d.fill(this.triangle);
	}

	/**
	 * Function to draw a triangle with a specified color
	 * 
	 * @param g -
	 *            Graphic context to receive drawings
	 * @param c -
	 *            Color to fill the triangle.
	 */

	public void draw(Graphics g, Color c) {
		Graphics2D g2d = (Graphics2D) g;
		g2d.setColor(c);
		g2d.fill(this.triangle);
		g2d.setColor(Color.BLACK);
		g2d.setStroke(new BasicStroke(1));
		g2d.draw(this.triangle);
	}

	/**
	 * Method that draws a disk given the graphic context and the color array
	 * Obs.: Please, reuse the ColorSet enum, when calling this method.
	 * 
	 * @param g2d -
	 *            Graphic context to receive the drawings
	 * @param cArray -
	 *            Array of colors, 6 colors, to paint a game disk
	 */
	public void drawDisk(Graphics2D g2d, Color[] cArray) {
		for (int i = 0; i < cArray.length; ++i) {
			rotate(g2d, 60);
			draw(g2d, cArray[i]);
		}
	}

	public void drawDisk(Graphics2D g2d, Disk d) {
		this.hexagonView.draw(g2d, new HexagonShape(this.triangle.getTop(), 50));
		for (int i = 0; i < d.getColorSet().length; i++) {
			rotate(g2d, 60);
			draw(g2d, d.getColorSet()[i]);
		}
		
	}

	/**
	 * Method that receives a array of disk and outputs in the graphic context
	 * the complete roullette
	 * 
	 * @param g2d -
	 *            the graphic context
	 * @param dArray -
	 *            the array of disk
	 */
	public void drawRoullette(Graphics2D g2d, Disk[] dArray) {
		double distanceFromCenterToOtherCenter = 2 * this.triangle.getSide()
				* sin(toRadians(60));
		drawDisk(g2d, dArray[0]);
		translate(g2d, distanceFromCenterToOtherCenter, 30);
		for (int i = 1; i < dArray.length; i++) {
			drawDisk(g2d, dArray[i]);
			translate(g2d, distanceFromCenterToOtherCenter, 30 + i * 300 - 60);
		}
	}

	/**
	 * Method that receives a roullette and outputs in the graphic context the
	 * complete roullette
	 * 
	 * @param g2d -
	 *            the graphic context
	 * @param r -
	 *            the roullette instance
	 */
	public void drawRoullette(Graphics2D g2d, Roullette r) {
		double distanceFromCenterToOtherCenter = 5 + 2
				* this.triangle.getSide() * sin(toRadians(60));
		drawDisk(g2d, r.getDiskSet()[0]);
		translate(g2d, distanceFromCenterToOtherCenter, 30);
		for (int i = 1; i < r.getDiskSet().length; i++) {
			drawDisk(g2d, r.getDiskSet()[i]);
			translate(g2d, distanceFromCenterToOtherCenter, 30 + i * 300 - 60);
		}
	}

	public Shape rotate(double angDegrees) {
		AffineTransform ar = AffineTransform
				.getRotateInstance(toRadians(angDegrees));
		ar.setToRotation(toRadians(angDegrees), this.triangle.getTop().getX(),
				this.triangle.getTop().getY());
		return ar.createTransformedShape(this.triangle);
	}

	public void rotate(Graphics2D g2d, double angDegrees) {
		g2d.rotate(toRadians(angDegrees), this.triangle.getTop().getX(),
				this.triangle.getTop().getY());
		g2d.setColor(this.color);
		g2d.fill(this.triangle);
	}

	public void translate(Graphics2D g2d, Point.Double translationPoint) {
		g2d.translate(translationPoint.x, translationPoint.y);
	}

	public void translate(Graphics2D g2d, double lenghtToTranslate,
			double angleInDegrees) {
		double x = lenghtToTranslate * cos(toRadians(angleInDegrees));
		double y = lenghtToTranslate * sin(toRadians(angleInDegrees));
		g2d.translate(x, y);
	}

	public Point2D.Double getCenter() {
		return center;
	}

	public void setCenter(Point2D.Double center) {
		this.center = center;
	}

}
